package com.css.fxfzypg.modules.saresults.util;

import com.css.fxfzypg.modules.saresults.entity.DzqhJournalEntity;
import com.css.fxfzypg.modules.saresults.service.SaResultsService;
import com.css.fxfzypg.modules.saresults.service.impl.SaResultsServiceImpl;
import com.css.fxfzypg.util.PlatformDateUtils;
import com.css.fxfzypg.util.UUIDGenerator;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Component
public class RecordUtils {

    @Autowired
    private SaResultsService saResultsService;


    /**
     * 注解列表(添加了@LogCompar的属性集合，数组的第一位是属性Field，第二位是注解LogCompar)
     */
    private static List<Object[]> fields;

    /**
     * 比较变更前后的数据，记录下添加了@LogCompar注解的属性，由原来的什么值变为了现在的什么值
     *
     * @param oldObj 原数据对象
     * @param newObj 新数据对象
     */
    public ArrayList<DzqhJournalEntity> addChangeRecord(Object oldObj, Object newObj, String id, String tableName, String userName, String orgName, String userId) {
        try {
            ArrayList<DzqhJournalEntity> list = new ArrayList<>();
            // 获取Class对象
            Class<?> oldClazz = oldObj.getClass();
            Class<?> newClazz = newObj.getClass();
            if (!oldClazz.equals(newClazz)) {
                throw new RuntimeException("请传入两个相同的实体类对象！");
            }
            fields = getFields(oldClazz);
            if (fields.size() == 0) {
                throw new RuntimeException("没有找到要对比的属性！");
            }

            // 根据注解列表，循环比较属性是否变化
            for (Object[] os : fields) {
                DzqhJournalEntity entity = new DzqhJournalEntity();
                Field field = (Field) os[0];
                LogCompar logCompar = (LogCompar) os[1];
                // 获取新旧的属性值
                Object oldValue = field.get(oldObj);
                Object newValue = field.get(newObj);
                if (oldValue == null) {
                    oldValue = logCompar.defaultValue();
                }
                if (newValue == null) {
                    newValue = logCompar.defaultValue();
                }
                // 若新值和旧值相等，则跳过
                if (oldValue == newValue || newValue.equals(oldValue)) {
                    continue;
                }
                // 若是BigDecimal类型，需要compareTo方法判断是否相等,相等则跳过
                if (field.getType() == BigDecimal.class && ((BigDecimal) newValue).compareTo((BigDecimal) oldValue) == 0) {
                    continue;
                }
                if (StringUtils.isNotBlank(logCompar.readConverterExp())) {
                    oldValue = convertByExp(oldValue.toString(), logCompar.readConverterExp(), logCompar.separator());
                    newValue = convertByExp(newValue.toString(), logCompar.readConverterExp(), logCompar.separator());
                } else if (StringUtils.isNotBlank(logCompar.dateFormat())) {
                    SimpleDateFormat dateFormat = new SimpleDateFormat(logCompar.dateFormat());
                    oldValue = dateFormat.parse(oldValue.toString());
                    newValue = dateFormat.parse(newValue.toString());
                }
                entity.setJournalId(UUIDGenerator.getUUID());
                entity.setProjectId(id);
                entity.setOperation("修改");
                entity.setField(logCompar.value());
                if(!isUUID32(oldValue.toString())){
                    entity.setBeforeUpdating(oldValue.toString());
                    entity.setAfterUpdate(newValue.toString());
                }
                if(tableName.equals("测线信息表格") || tableName.equals("地质剖面信息表格")){
                    if(isUUID32(oldValue.toString())){
                        entity.setBeforeUpdating(getById(oldValue.toString()));
                        entity.setAfterUpdate(getById(newValue.toString()));
                    }else {
                        entity.setBeforeUpdating(oldValue.toString());
                        entity.setAfterUpdate(newValue.toString());
                    }
                }
                entity.setOperationTime(PlatformDateUtils.getCurrentDate());
                entity.setStatus("0");
                entity.setTableName(tableName);
                entity.setUserName(userName);
                entity.setOperationUser(userId);
                entity.setCompany(orgName);
                list.add(entity);
            }
            return list;
        } catch (IllegalAccessException e) {
            log.error(e.getMessage());
            throw new RuntimeException(e.getMessage());
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    private  String getById(String str){
        return saResultsService.getByAreaId(str);
    }

    /**
     * 获取注解属性信息
     */
    private static List<Object[]> getFields(Class<?> clazz) {
        List<Object[]> fields = new ArrayList<Object[]>();
        List<Field> tempFields = new ArrayList<>();
        tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields()));
        tempFields.addAll(Arrays.asList(clazz.getDeclaredFields()));
        for (Field field : tempFields) {
            if (field.isAnnotationPresent(LogCompar.class)) {
                LogCompar logCompar = field.getAnnotation(LogCompar.class);
                if (logCompar != null) {
                    // 设置可以访问私有private的属性
                    field.setAccessible(true);
                    fields.add(new Object[]{field, logCompar});
                }
            }
        }
        return fields;
    }

    /**
     * 解析值
     *
     * @param propertyValue
     * @param converterExp
     * @param separator
     * @return
     */
    private static String convertByExp(String propertyValue, String converterExp, String separator) {
        StringBuilder stringBuilder = new StringBuilder();
        String[] convertSource = converterExp.split(",");
        for (String item : convertSource) {
            String[] itemArray = item.split("=");
            if (StringUtils.containsAny(separator, propertyValue)) {
                for (String value : propertyValue.split(separator)) {
                    if (itemArray[0].equals(value)) {
                        stringBuilder.append(itemArray[1] + separator);
                        break;
                    }
                }
            } else if (itemArray[0].equals(propertyValue)) {
                return itemArray[1];
            }
        }
        return StringUtils.stripEnd(stringBuilder.toString(), separator);
    }

    /**
     * 判断是否是uuid
     * @param uuid
     * @return
     */
    public static boolean isUUID32(String uuid) {
        String[] split = uuid.split(",");
        for (String str : split) {
            if (str == null || str.length() != 32) {
                return false;
            }
            for (int i = 0; i < 32; i++) {
                if (!Character.isLetterOrDigit(str.charAt(i))) {
                    return false;
                }
            }
        }
        return true;
    }
}